package org.xurui.sxl.protocol.command.impl;

import lombok.extern.slf4j.Slf4j;
import org.jetlinks.core.message.CommonDeviceMessage;
import org.jetlinks.core.message.DeviceMessage;
import org.jetlinks.core.message.codec.EncodedMessage;
import org.jetlinks.core.message.codec.FromDeviceMessageContext;
import org.jetlinks.core.message.function.FunctionInvokeMessage;
import org.jetlinks.core.message.function.FunctionInvokeMessageReply;
import org.jetlinks.core.message.function.FunctionParameter;
import org.xurui.sxl.protocol.cache.ConcurrentMapCache;
import org.xurui.sxl.protocol.command.CmdCodec;
import org.xurui.sxl.protocol.enums.CommandEnum;
import org.xurui.sxl.protocol.utils.BinaryUtils;
import org.xurui.sxl.protocol.utils.NumberUtils;
import org.xurui.sxl.protocol.utils.SxlMessageUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 限制运营商
 */
@Slf4j
public class CmdCodec_MNC implements CmdCodec {
    @Override
    public boolean supportsCmd(String cmd) {
        return CommandEnum.MNC.name().equals(cmd);
    }

    @Override
    public boolean supportsRelayCmd() {
        return true;
    }

    @Override
    public List<DeviceMessage> parsePayload(String payload, FromDeviceMessageContext context) {
        //TODO MNC
        //设备回复格式：*XX,YYYYYYYYYYYYYYY,V4,MNC,seq,para,HHMMSS,S,latitude,D,longitude,G,speed,pdop,DDMMYY,tracker_status#
        //设备回复示例：*TE,2020916301,V4,MNC,130305,1,1,00,2,02,3,04,4,07,5,08,6,13,130306,V,2230.7021,N,11355.1445,E,0.00,2.8,271112,FFFFFFFF#
        FunctionInvokeMessageReply report = FunctionInvokeMessageReply.create();
        String[] payloadArr = payload.replaceAll("\\*","").split(",");
        String deviceId = payloadArr[1];
        report.setDeviceId(deviceId);
        Object messageIdObj = ConcurrentMapCache.getInstance().getAndRemove(deviceId+"_"+CommandEnum.MNC.name()+"_"+payloadArr[4]);
        String messageId = messageIdObj==null?null:messageIdObj.toString();
        if(messageId==null){
            messageId = deviceId+"_"+payloadArr[4];
        }

        report.setFunctionId(CommandEnum.MNC.name());
        report.setMessageId(messageId);
        report.setTimestamp(System.currentTimeMillis());
        /*String para="";
        int j=7;
        if(payloadArr[5].equals("1")){
            j=17;
            para=ConcurrentMapCache.getInstance().get(payloadArr[5]+","+payloadArr[6]+","+payloadArr[7]+","+payloadArr[8]+","+payloadArr[9]+","+payloadArr[10]+","+payloadArr[11]+","+payloadArr[12]+","+payloadArr[13]+","+payloadArr[14]+","+payloadArr[15]+","+payloadArr[16]+","+payloadArr[17]).toString();
        }else if(payloadArr[5].equals("2")){
            j=12;
            para=ConcurrentMapCache.getInstance().get(payloadArr[5]+","+payloadArr[6]+","+payloadArr[7]+","+payloadArr[8]+","+payloadArr[9]+","+payloadArr[10]+","+payloadArr[11]+","+payloadArr[12]).toString();
        }else if(payloadArr[5].equals("3")){
            j=10;
            para=ConcurrentMapCache.getInstance().get(payloadArr[5]+","+payloadArr[6]+","+payloadArr[7]+","+payloadArr[8]+","+payloadArr[9]+","+payloadArr[10]).toString();
        }else if(payloadArr[5].equals("4")){
            j=24;
            para=ConcurrentMapCache.getInstance().get(payloadArr[5]+","+payloadArr[6]+","+payloadArr[7]+","+payloadArr[8]+","+payloadArr[9]+","+payloadArr[10]+","+payloadArr[11]+","+payloadArr[12]+","+payloadArr[13]+","+payloadArr[14]+","+payloadArr[15]+","+payloadArr[16]+","+payloadArr[17]+","+payloadArr[18]+","+payloadArr[19]+","+payloadArr[20]+","+payloadArr[21]+","+payloadArr[22]+","+payloadArr[23]+","+payloadArr[24]).toString();
        }else if(payloadArr[5].equals("0")){

            para=ConcurrentMapCache.getInstance().get(payloadArr[5]+","+payloadArr[6]+","+payloadArr[7]).toString();
        }*/
        String[] paraArr= Arrays.copyOfRange(payloadArr,4,payloadArr.length-10);
        String para="";
        for (int i=1;i<paraArr.length;i++){
            // System.out.println(paraArr[i]);
            if(i==1){
                para=paraArr[i];
            }else{
                para=para+","+paraArr[i];
            }
        }
        int j=4+paraArr.length-1;

        Map<String, Object> properties = new HashMap<>();
        properties.put("para",para);
        properties.put("uptime",payloadArr[j+1]);
        properties.put("s",payloadArr[j+2]);
        properties.put("latitude",BinaryUtils.getWgs84LonLat(payloadArr[j+3],"lat"));
        properties.put("d",payloadArr[j+4]);
        properties.put("longitude",BinaryUtils.getWgs84LonLat(payloadArr[j+5],"lon"));
        properties.put("g",payloadArr[j+6]);
        properties.put("speed", NumberUtils.parseDouble(payloadArr[j+7]));
        properties.put("pdop",NumberUtils.parseDouble(payloadArr[j+8]));
        properties.put("upday", payloadArr[j+9]);
        String trackerStatusHex = payloadArr[j+10];


        Map<String,Object> trackerStatusMap = parseTrackerStatus(trackerStatusHex);
        properties.put("trackerstatus",trackerStatusMap);
        report.setOutput(properties);

        //TODO 更新状态
        return genDeviceMessage(report);
    }

    @Override
    public EncodedMessage encodeMessage(CommonDeviceMessage message,String zzs) {
        //平台下发消息  TODO MNC
        //格式：*XX,YYYYYYYYYYYYYYY,MNC,HHMMSS,SWITCH,NUM_1,MNC_1,NUM_2,MNC_2,,#
        //例子 1 *TE,2020916301,MNC,130305,1,1,00,2,02,3,04,4,07,5,08,6,13# //只允许使用移动卡 00,02,04,07,08,13
        //例 2 *TE,2020916301,MNC,130305,2,1,01,2,06,3,09,4,10# //仅联通 01,06,09,10
        //例 3 *TE,2020916301,MNC,130305,3,1,03,2,11,3,12# //仅电信 03,11,12
        //例 4 *TE,2020916301,MNC,130305,0,1,00# //不限制
        //例 5 *TE,2020916301,MNC,130305,4,1,00,2,02,3,04,4,07,5,08,6,13,7,01,8,06,9,09,10,10# //仅移动和联通
        //参数说明：SWITCH 功能开关，0-不限制，1-仅移动，2-仅联通，3-仅电信，4-其他
        //参数说明：NUM MNC 编号，最大 10，即最多设置 10 个
        //参数说明：MNC 移动设备网络代码，中国移动=00，中国联通=01,中国电信=11，删除为空 1,,2
        if(message instanceof FunctionInvokeMessage) {
            FunctionInvokeMessage m = (FunctionInvokeMessage) message;
            List<FunctionParameter> params = m.getInputs();
            Map<String, Object> paramsMap = params.stream()
                .collect(Collectors.toMap(FunctionParameter::getName, FunctionParameter::getValue));
            String switchF="0";
            if(paramsMap.get("switch")!=null && !paramsMap.get("switch").equals("")) {
                switchF=paramsMap.get("switch").toString();
            }
            String[] mesArr= new String[]{};
            if(paramsMap.get("mnc")!=null && !paramsMap.get("mnc").equals("")) {
                mesArr=paramsMap.get("mnc").toString().split(",");
            }
            if(mesArr.length==0){
                log.error("移动设备网络代码为空请重新填写");
                return null;
            }

            String time = SxlMessageUtils.getTimeHHMMSS();//DateFormatUtils.format(new Date(),"HHmmss");
           /* StringBuffer sb = new StringBuffer();
            sb.append("*");
            sb.append(zzs);//TODO 需要修改成根据设备动态加载
            sb.append(",");
            sb.append(message.getDeviceId());
            sb.append(",");
            sb.append(CommandEnum.MNC.name());
            sb.append(",");
            sb.append(time);
            sb.append(",");
            sb.append(switchF);
            boolean bs=false;
            for (int i=0;i<mesArr.length;i++){
                sb.append(",");
                sb.append((i+1));
                bs=BinaryUtils.isMNC(switchF,mesArr[i]);
                if(!bs){
                    break;
                }
                sb.append(",");
                sb.append(mesArr[i]);

            }
            if(!bs){
                log.error("该参数MNC存在错误请根据功能开关进行传递！");
            }*/
           /* if(switchF.equals("0")){
                boolean bs=false;
                for (int i=1;i<mesArr.length;i++){
                    if(i%2==0){
                        bs=BinaryUtils.isMNC(mesArr[0],mesArr[i]);
                        if(!bs){
                            break;
                        }
                        sb.append(",");
                        sb.append(mesArr[i]);
                        sb.append(",");
                    }else{
                        sb.append(mesArr[i]);
                    }

                }
                if(!bs){
                    log.error("该参数MNC存在错误请根据功能开关进行传递！");
                }
            }else  if(switchF.equals("1")){
                boolean bs=false;
                for (int i=1;i<mesArr.length;i++){
                    if(i%2==0){
                        bs=BinaryUtils.isMNC(mesArr[0],mesArr[i]);
                        if(!bs){
                            break;
                        }
                        sb.append(",");
                        sb.append(mesArr[i]);
                        sb.append(",");
                    }else{
                        sb.append(mesArr[i]);
                    }

                }
                if(!bs){
                    log.error("该参数MNC存在错误请根据功能开关进行传递！");
                }
            }else  if(switchF.equals("2")){
                boolean bs=false;
                for (int i=1;i<mesArr.length;i++){
                    if(i%2==0){
                        bs=BinaryUtils.isMNC(mesArr[0],mesArr[i]);
                        if(!bs){
                            break;
                        }
                        sb.append(",");
                        sb.append(mesArr[i]);
                        sb.append(",");
                    }else{
                        sb.append(mesArr[i]);
                    }

                }
                if(!bs){
                    log.error("该参数MNC存在错误请根据功能开关进行传递！");
                }
            }else  if(switchF.equals("3")){
                boolean bs=false;
                for (int i=1;i<mesArr.length;i++){
                    if(i%2==0){
                        bs=BinaryUtils.isMNC(mesArr[0],mesArr[i]);
                        if(!bs){
                            break;
                        }
                        sb.append(",");
                        sb.append(mesArr[i]);
                        sb.append(",");
                    }else{
                        sb.append(mesArr[i]);
                    }

                }
                if(!bs){
                    log.error("该参数MNC存在错误请根据功能开关进行传递！");
                }
            }else  if(switchF.equals("4")){
                boolean bs=false;
                for (int i=1;i<mesArr.length;i++){
                    if(i%2==0){
                        bs=BinaryUtils.isMNC(mesArr[0],mesArr[i]);
                        if(!bs){
                            break;
                        }
                        sb.append(",");
                        sb.append(mesArr[i]);
                        sb.append(",");
                    }else{
                        sb.append(mesArr[i]);
                    }

                }
                if(!bs){
                    log.error("该参数MNC存在错误请根据功能开关进行传递！");
                }
            }*/

         /*   sb.append("#");*/
            SxlMessageUtils.SxlCmd sxlCmd=SxlMessageUtils.SxlCmd.getInstance();
            sxlCmd.appendAndAddSeparator(zzs)
                .appendAndAddSeparator(message.getDeviceId())
                .appendAndAddSeparator(CommandEnum.MNC.name())
                .appendAndAddSeparator(time)
                .append(switchF);

            boolean bs=false;
            for (int i=0;i<mesArr.length;i++){
                sxlCmd.append(SxlMessageUtils.CMD_SEPARATION)
                .append(String.valueOf((i+1)));
                bs=BinaryUtils.isMNC(switchF,mesArr[i]);
                if(!bs){
                    break;
                }
                sxlCmd.append(SxlMessageUtils.CMD_SEPARATION)
                .append(mesArr[i]);

            }
            if(!bs){
                log.error("该参数MNC存在错误请根据功能开关进行传递！");
            }

            ConcurrentMapCache.getInstance().set(message.getDeviceId()+"_"+CommandEnum.MNC.name()+"_"+time,message.getMessageId(),60*3*1000);
            //return EncodedMessage.simple(Unpooled.wrappedBuffer(sb.toString().getBytes()));

            return sxlCmd.buildEncodeMessage();
        }else{
            if (log.isDebugEnabled()) {
                log.debug("非FunctionInvokeMessage指令{}消息{}",CommandEnum.WIFISCAN.name(),message);
            }
            return null;
        }
    }
}
